<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2009 Mitch Amiano (Mitch.C.Amiano@AgileMarkup.com)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->

<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:xlink="http://www.w3.org/1999/xlink"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   xmlns="http://www.w3.org/1999/xhtml"
   xmlns:xhtml="http://www.w3.org/1999/xhtml"
   xmlns:msxsl="urn:schemas-microsoft-com:xslt"
   exclude-result-prefixes="xlink msxsl exsl inkscape sodipodi svg am xhtml" 
   xmlns:exsl="http://exslt.org/common"
   xmlns:am="http://www.agilemarkup.com/2009/xmlintegration"
   xmlns:amd="http://www.agilemarkup.com/2009/xmlintegration"
   extension-element-prefixes="exsl amd"
   >
   <xsl:import href="atramentum_jquery.xsl" />
   <xsl:import href="atramentum_splinter.xsl" />
  
  
<amd:purpose>This stylesheet module uses an xsltproc extension element  to output  
  files defining a "skin", and/or custom library of Web widgets. 
  
  The standard result document is  used strictly as a return value to . 
  the Inkscape extension script which invoked the transform. 
  We can use the result document to direct behavior in the extension script.
  But even if not, the standard result doc is captured in a way that can be debugged. 
</amd:purpose>
  
<xsl:output method="xml" encoding="UTF-8"  omit-xml-declaration="no" indent="yes"/>
<xsl:preserve-space elements="*"/>

<am:purpose>Set the file path to the output files</am:purpose>
<xsl:param name="base_dir" select="'.'"/>
<am:purpose>Produce divs and CSS styles for any objects marked as figures.</am:purpose>
<xsl:param name="gopngs" select="true()"/>
<am:purpose>Include basic JQuery hooks for articulating objects.</am:purpose>
<xsl:param name="gojquery" select="true()"/>
<am:purpose>Include jquery hook to navigate links.</am:purpose>
<xsl:param name="golinks" select="true()"/>
  
<am:purpose>Split off or "splinter" widgets' SVG so that they can be placed discretely on the page, 
    in addition to or instead of using PNG files. The SVGWeb project makes this feasible under 
    non-standard (Microsoft) browsers.
</am:purpose>
<xsl:param name="gosplinter" select="false()"/>  

<am:purpose>Set the default prefix for making output file names.</am:purpose>
<xsl:param name="base_name" select="'TestFile'" />

<am:purpose>We may expose other JQuery articulations as Inkscape parameters. 
  So to check whether JQuery is needed at all do an "or" of each of the boolean params which require JQuery.
</am:purpose>
<xsl:variable name="requirejquery" select="$gojquery"/>
  
<am:purpose>Match doc root, set up XHTML file and CSS</am:purpose>
<xsl:template match="/svg:svg">
<am:moduleoutput>
  <exsl:document href="{$base_dir}/{$base_name}.html" 
    method="xml" encoding="UTF-8"  indent="yes"
    omit-xml-declaration="yes" media-type="text/xml+xhtml"
    doctype-system="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"
    doctype-public="-//W3C//DTD XHTML 1.1//EN"
    >
    <html xml:lang="en" lang="en"  xsl:exclude-result-prefixes="xhtml">
      <head>
         <title>ATRAMENTUM OUTPUT</title>
        <xsl:if test="$gosplinter">
          <xsl:call-template  name="splinter_init" />
        </xsl:if>
	 <link rel="stylesheet" href="{$base_name}.css" type="text/css"/>
       <xsl:if test="$requirejquery">
         <xsl:call-template name="jquery_init" />
       </xsl:if>
      </head>
      <body>
        
      <xsl:apply-templates select="svg:g[@inkscape:groupmode='layer']" mode="xhtml" />
        
      <xsl:if test="$requirejquery">
        <xsl:call-template name="jquery_content"/>
      </xsl:if>
        
      <xsl:if test="$gosplinter">
          <xsl:apply-templates mode="splinter_content" />
          <xsl:apply-templates mode="splinter" />
      </xsl:if>
        
      </body>
    </html>
  </exsl:document>
  
  <exsl:document href="{$base_dir}/{$base_name}.css" 
    method="text" encoding="UTF-8" 
    omit-xml-declaration="yes" media-type="text/css" 
    >
    <xsl:if test="$requirejquery">
      <xsl:call-template name="jquery_css"/>
    </xsl:if>
    <xsl:apply-templates select="/svg:svg" mode="css" />
  </exsl:document>
  
</am:moduleoutput>
</xsl:template>

<am:purpose>Generate HTML content for the inkscape layers and graphic objects.</am:purpose>
<!--
  Here's how it works:
  0) First, the Python script turns off visibility for every layer. For each layer,
       it turns visiblity back on, and turns off visibility for all child groups. 
       For each child group, it loops and exports an image (if the options are set to do exports).
       Then this XSLT module is invoked. 
  
  1) For each svg/g element that has @inkscape:groupmode="layer",
       if _wrap is set,
       make a div and set @class="alayer" and @id from the g/@id. 

  2) For each direct child of a layer being a non-layer g element having a 
      rect with an @id tagged as "_img", giving x and y attributes, 
      make HTML img elements (png) and set positions absolutely.
      If tagged with _wrap, place in a div.
      
   3) For each other element tagged as "_img", make an HTML img.
       If tagged with _wrap, place in a div.
-->
<xsl:template match="svg:g[@inkscape:groupmode='layer']" mode="xhtml">
  <xsl:choose>
    <xsl:when test="contains(@id,'_wrap')">
      <div id="{substring-before(@id, '_')}" title="{substring-after(@inkscape:label,'#')}" class="alayer">
        <xsl:text>&#xA;</xsl:text>
        <xsl:apply-templates mode="xhtml"/>
      </div>
      <xsl:text>&#xA;</xsl:text>
    </xsl:when>
    <xsl:otherwise>
      <xsl:apply-templates mode="xhtml"/>
    </xsl:otherwise>
  </xsl:choose> 
</xsl:template>

<xsl:template match="svg:rect[contains(@id,'_bgimg')]" mode="xhtml">
   <div id="{substring-before(@id, '_')}" title="{substring-after(@inkscape:label,'#')}" >
     <xsl:call-template name="process_img"/> 
   </div>
   <xsl:text>&#xA;</xsl:text>
</xsl:template>
  
  <!-- Part (2): Process any groups which have a rect tagged as _img  -->
  <xsl:template match="svg:g[ svg:rect[ contains(@id,'_img') ] ]" mode="xhtml">
    <xsl:choose>
      <xsl:when test="contains( svg:rect[1]/@id,'_wrap')">
        <div id="{substring-before(svg:rect[1]/@id,'_')}" title="{substring-after(svg:rect[1]/@inkscape:label,'#')}" class="awrap">
          <xsl:text>&#xA;</xsl:text>
          <xsl:for-each select="rect[1]">
          <xsl:call-template name="process_img"/> 
          </xsl:for-each>
        </div>
        <xsl:text>&#xA;</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:for-each select="rect[1]">
          <xsl:call-template name="process_img"/> 
        </xsl:for-each>
      </xsl:otherwise>
    </xsl:choose> 
  </xsl:template>

   <!-- Part (2): Process any layer non-group child objects.
     (A group which is itself tagged as "_img" may also be processed here unless
     it contains a child rect also tagged as "_img".)
   -->
  <xsl:template match="svg:*[ contains(@id,'_img') ]" mode="xhtml">
    <xsl:choose>
      <xsl:when test="contains( @id,'_wrap')">
        <div id="{substring-before(@id,'_')}" title="{substring-after(@inkscape:label,'#')}" class="awrap">
          <xsl:text>&#xA;</xsl:text>
            <xsl:call-template name="process_img"/> 
        </div>
        <xsl:text>&#xA;</xsl:text>
      </xsl:when>
      <xsl:otherwise>
          <xsl:call-template name="process_img"/> 
      </xsl:otherwise>
    </xsl:choose> 
  </xsl:template>
  
  <!-- this is a workhorse function, doing the formatting of the XHTML whether the widget 
         was drawn as a single object or was a group of objects with a bounding rect.
         -->
  <xsl:template name="process_img">
    <xsl:variable name="draggableclass">
      <xsl:if test="$gojquery and contains(@id,'_drag')"> draggable </xsl:if>
    </xsl:variable>
    
    <xsl:variable name="linksclass">
      <xsl:if test="$golinks and contains(@id,'_link')"> link </xsl:if>
    </xsl:variable>   
    
    <xsl:if test="$gopngs">
     <xsl:text> </xsl:text>
      <img id="{substring-before(@id,'_')}" class=" img {$draggableclass}{$linksclass}" alt="{ concat( substring-after(@inkscape:label,'#'), substring(substring-before(@id,'_'), (@inkscape:label!='')*string-length(substring-before(@id,'_'))+1)) }" src="{substring-before(@id,'_')}.png" />
      <xsl:text>&#xA;</xsl:text>
    </xsl:if>
  </xsl:template>

  <xsl:template match="text()" mode="xhtml"/>
  <xsl:template match="*" mode="xhtml">
    <xsl:apply-templates mode="xhtml"/>
  </xsl:template>


<!-- Mode: CSS 
       Produce CSS styles for inclusion in head or external file:
       
       1) Using the very first svg/g with @inkscape:groupmode="layer"
       look for a "rect" child w/ @width, @height, @id containing "_bgimg" and 
       declare a CSS class 'alayer' using the rect for the CSS properties;
       or a "rect" child with @id containing "_bgcolor" and set the body background-color 
       from the style fill: property. 
        
       2) For each of the g's with an inkscape groupmode of layer, define a CSS @id rule.
       
       3) For each g with a rect child w/ @id containing "_img" 
       declare a CSS @id rule for positioning. 
       
       4) For an ungrouped object with an "_img" @id, declare a CSS rule.
       
-->
  <xsl:template match="svg:svg" mode="css">
    <xsl:text>/* CSS Styles for sliced layers */&#xA; </xsl:text>
    <xsl:for-each select="(svg:g[@inkscape:groupmode='layer'])[1]/svg:rect[contains(@id,'_bgimg')]">
      <xsl:text>div.alayer {&#xA;</xsl:text>
      <xsl:text> display: block; margin-left: auto; margin-right: auto;&#xA;</xsl:text>
      <xsl:call-template name="CSSPosition" />
      <xsl:text>}&#xA;</xsl:text>
    </xsl:for-each>
    <xsl:for-each select="(svg:g[@inkscape:groupmode='layer'])[1]/svg:rect[contains(@id,'_bgcolor')][1]">
      <xsl:text>body {&#xA;</xsl:text>
      <xsl:text> background-color: &#xA;</xsl:text>
      <xsl:call-template name="parseStyles">
        <xsl:with-param name="styles" select="@style"/>
        <xsl:with-param name="stylename" select="'fill'" />
      </xsl:call-template>
      <xsl:text>}&#xA;</xsl:text>
    </xsl:for-each>    
    <xsl:apply-templates mode="css"/>
  </xsl:template>
  
  <xsl:template match="svg:g[@inkscape:groupmode='layer']" mode="css">
    <xsl:value-of select="concat('#',substring-before(@id,'_'),' {  /* ', @inkscape:label, '*/&#xA;')" />
    <xsl:for-each select="svg:rect[contains(@id,'_bgimg') ]"> background-image: url(<xsl:value-of select="substring-before(@id,'_')"/>.png);&#xA;</xsl:for-each> 
    <xsl:call-template name="CSSPosition" />  
    <xsl:text>}&#xA;</xsl:text>
    <xsl:apply-templates mode="css"/>
  </xsl:template>

  <xsl:template match="svg:g" mode="css">
    <xsl:apply-templates mode="css"/>
  </xsl:template>

  <xsl:template match="svg:rect[contains(@id,'_img')]" mode="css">
    <xsl:if test="$gopngs">
    <xsl:value-of select="concat('#', substring-before(@id,'_'),' {&#xA;')" />
    <xsl:call-template name="CSSPosition" />  
    <xsl:text>}&#xA;</xsl:text>
    </xsl:if>
  </xsl:template>

  <xsl:template match="svg:*[contains(@id,'_img')]" mode="css">
    <xsl:if test="$gopngs">
    <xsl:value-of select="concat('#', substring-before(@id,'_'),' {&#xA;')" />
    <xsl:text>}&#xA;</xsl:text>
    </xsl:if>
  </xsl:template>
  
  <xsl:template match="text()" mode="css"/>
  
  <!-- parse an SVG style attribute to get a particular value -->
  <xsl:template name="parseStyles">
    <xsl:param name="stylename" select="'fill'"/>
    <xsl:param name="styles" select="@style"/>
    <xsl:value-of select="substring-before(substring-after($styles,$stylename), ';')" />
  </xsl:template>
  
  <!-- return CSS style rules for absolute position -->
  <xsl:template name="CSSPosition">
    <xsl:text> position: absolute;&#xA;</xsl:text>
    <xsl:value-of select="concat(' top: ', round(@y),'px;&#xA;')"/>
    <xsl:value-of select="concat(' left: ', round(@x), 'px;&#xA;')"/>
  </xsl:template>
  
  <!-- return CSS style rules for fixed size -->
  <xsl:template name="CSSSize">
    <xsl:value-of select="concat(' width: ', round(@width) , 'px;&#xA;')"/>
    <xsl:value-of select="concat(' height: ', round(@height), 'px;&#xA;')"/>
  </xsl:template>
  
</xsl:stylesheet>
